import XLSX from 'xlsx'
import XLSXStyle from 'xlsx-style'
import _ from 'lodash'
import { saveAs } from 'file-saver'

function s2ab (s) {
  const buf = new ArrayBuffer(s.length)
  const view = new Uint8Array(buf)
  for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
  return buf
}

/**
 * 导出时间开动率excel
 * @param companyName 公司名称
 * @param dataRange 日期/时间区间
 * @param workshop 分厂车间
 * @param sheetName 工作簿名
 * @param excelName 表格名
 * @param headList 表头
 * @param tableData 表格数据
 */
function availabilityExcel (companyName, dataRange, workshop, sheetName, excelName, headList, tableData) {
  const length = 10
  // 合并公司名称
  const companyMerge = _getMergeConfig(0, 0, length, 0)
  // 合并日期区间
  const dataRangeMerge = _getMergeConfig(0, 1, length, 1)
  // 合并分厂车间单元格
  // const workshopMerge = _getMergeConfig(1, 2, length, 2)
  // 表格详细
  const tableDetails = getTableDetails(headList, tableData)
  // 添加标题，停机原因，所在位置, 标题栏的数据
  const ws = XLSX.utils.aoa_to_sheet([[companyName], [dataRange], ...tableDetails])
  // 获取列宽
  ws['!cols'] = calcColWidth(tableDetails)
  // 首列固宽20
  ws['!cols'][0].wch = 20
  // 定义行高
  // ws['!rows'] = [{ hpx: 36 }, { hpx: 24 }, { hpx: 24 }, { hpx: 24 }, { hpx: 24 }, { hpx: 24 }, { hpx: 24 }]

  // 添加合并的config
  ws['!merges'] = [companyMerge, dataRangeMerge]
  // 生成样式
  _generateStyle(ws)
  // 创建一个空的sheet
  const wb = XLSX.utils.book_new()
  // 添加sheet
  XLSX.utils.book_append_sheet(wb, ws, sheetName)
  const wbout = XLSXStyle.write(wb, {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  })
  saveAs(new Blob([s2ab(wbout)], {
    type: 'application/octet-stream'
  }), `${excelName}.xlsx`)
}

/**
 * 获取表格详细
 * @param headList 表头
 * @param tableData 表格数据
 * @returns {[]} 待导出表格详细
 */
function getTableDetails (headList, tableData) {
  let data = [headList]

  tableData.forEach((item, index) => {
    let row = [item.deviceName, item.location]
    for (let i in item) {
      if (!_.isNaN(Number(i))) {
        row.push(item[i])
      }
    }
    row.push(item.average)
    data.push(row)
  })
  return data
}

function calcColWidth (tableData) {
  const colWidth = [...tableData].map(row => row.map(val => {
    /* 先判断是否为''/undefined */
    if (!val) {
      return {
        'wch': 10
      }
      // 判断是否为中文
    } else if (/[\u4e00-\u9fa5]/.test(val.toString())) {
      return {
        'wch': val.toString().length * 2 > 10 ? val.toString().length * 2 : 10
      }
    } else {
      return {
        'wch': val.toString().length > 10 ? val.toString().length : 10
      }
    }
  }))
  // 每一列取最大宽度
  let result = colWidth[0]
  for (let i = 1; i < colWidth.length; i++) {
    for (let j = 0; j < colWidth[i].length; j++) {
      if (result[j]['wch'] < colWidth[i][j]['wch']) {
        result[j]['wch'] = colWidth[i][j]['wch']
      }
    }
  }
  return result
}

/**
 * 生成样式
 * @private
 */
function _generateStyle (ws) {
  // 居中
  const alignCenter = {
    horizontal: 'center',
    vertical: 'center'
  }
  const alignLeft = {
    horizontal: 'left',
    vertical: 'center'
  }
  // 单元格外侧框线
  const borderAll = {
    top: {
      style: 'thin'
    },
    bottom: {
      style: 'thin'
    },
    left: {
      style: 'thin'
    },
    right: {
      style: 'thin'
    }
  }
  const font = {
    name: '宋体',
    sz: 10
  }
  // 设置公司名称的样式
  ws['A1']['s'] = {
    fill: {
      fgColor: {
        rgb: 'FF558ed5' // 背景颜色,不要在前面加#号
      }
    },
    font: {
      name: '宋体',
      sz: 16,
      color: { rgb: 'FFFFFFFF' },
      height: 32,
      bold: false,
      italic: false,
      underline: false
    },
    alignment: alignCenter
  }
  // 设置停机原因的样式
  ws['A2']['s'] = {
    font: {
      name: '宋体',
      sz: 12,
      color: { rgb: '#FFFF0000' },
      bold: false,
      italic: false,
      underline: false
    },
    alignment: alignLeft
  }
  // // 设置所在位置的样式
  // ws['A3']['s'] = {
  //   font: {
  //     name: '宋体',
  //     sz: 12,
  //     color: { rgb: '#FFFF0000' },
  //     bold: false,
  //     italic: false,
  //     underline: false
  //   },
  //   alignment: alignCenter
  // }
  // // 设置所在位置的样式
  // ws['B3']['s'] = {
  //   font: {
  //     name: '宋体',
  //     sz: 12,
  //     color: { rgb: '#FFFF0000' },
  //     bold: false,
  //     italic: false,
  //     underline: false
  //   },
  //   alignment: alignLeft
  // }

  Object.keys(ws).forEach(item => {
    // 设置表头的样式
    if (/[A-Z]+3$/.test(item)) {
      ws[item]['s'] = {
        border: borderAll,
        fill: {
          fgColor: {
            rgb: 'FFB4C6E7' // 背景颜色,不要在前面加#号
          }
        },
        font: {
          name: '宋体',
          sz: 12
        },
        alignment: alignCenter
      }
    } else if (item.replace(/[^0-9]/ig, '') > 3) {
      if (_.startsWith(item, 'A')) {
        // 设置其余的单元格
        ws[item]['s'] = {
          font,
          border: borderAll,
          alignment: {
            horizontal: 'center',
            vertical: 'center',
            wrapText: true
          }
        }
      } else {
        // 设置其余的单元格
        ws[item]['s'] = {
          font,
          border: borderAll,
          alignment: alignCenter
        }
      }
    }
  })
}

/**
 * 根据参数返回单元格合并的配置信息
 * @param sc 开始列
 * @param sr 开始行
 * @param ec 结束列
 * @param er 结束行
 * @returns {{s: {r: *, c: *}, e: {r: *, c: *}}}
 * @private
 */
function _getMergeConfig (sc, sr, ec, er) {
  return {
    s: {
      c: sc,
      r: sr
    },
    e: {
      c: ec,
      r: er
    }
  }
}
export default {
  availabilityExcel
}
